/**
 * 
 */
package com.android.dwt.ui;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.Window;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SimpleExpandableListAdapter;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

import com.android.dwt.R;
import com.android.dwt.TaskItem;
import com.android.dwt.R.color;
import com.android.dwt.R.drawable;
import com.android.dwt.R.id;
import com.android.dwt.R.layout;
import com.android.dwt.R.string;
import com.android.dwt.data.DBTaskAdapter;
import com.android.dwt.data.GTDApp;
import com.android.dwt.service.DWTService;
import com.android.dwt.service.DWTService.MyBinder;
import com.android.dwt.util.C;
import com.android.dwt.util.TaskUtil;

/**
 * @author xlees
 *
 */
public class ViewTaskAct extends Activity
		implements OnEditorActionListener {
	
	/*
	 * My simple expandable list adapter
	 */
	private class MyListAdapter extends SimpleExpandableListAdapter
			implements ServiceConnection {
		
		private class ViewHolder {
			
			TextView prior;
			CheckBox cb;
			TextView title;
			TextView list;
			TextView context;
			TextView position;
//			TextView project;
			TextView tags;

			TextView flag;
		}
		
		
		private LayoutInflater mInflater;
		
		private DWTService mService;
		private boolean mBound;
		private boolean mChecked;
		
		public MyListAdapter(Context context,
				List<? extends Map<String, ?>> groupData, int groupLayout,
				String[] groupFrom, int[] groupTo,
				List<? extends List<? extends Map<String, ?>>> childData,
				int childLayout, String[] childFrom, int[] childTo) {
			
			super(context, groupData, groupLayout, groupFrom, groupTo, childData,
					childLayout, childFrom, childTo);
			// TODO Auto-generated constructor stub

			mInflater = LayoutInflater.from(context);
		}
		
		@Override
		public View getChildView(final int groupPosition, final int childPosition,
				boolean isLastChild, View convertView, ViewGroup parent) {
			
			// TODO Auto-generated method stub
//			return super.getChildView(groupPosition, childPosition, isLastChild,
//					convertView, parent);
			
			final ViewHolder holder;

			if (convertView == null) {
				
				convertView = mInflater.inflate(R.layout.row_task, null);

				holder = new ViewHolder();
				holder.prior = (TextView) convertView
						.findViewById(R.id.tv_row_prior);

				if (taskStatus == C.TASK.CANCELLED) { // remove the checkbox
					
					LinearLayout ll_row_top = ((LinearLayout) convertView
							.findViewById(R.id.ll_row_top));
					LinearLayout ll_row_cb = ((LinearLayout) convertView
							.findViewById(R.id.ll_row_cb));
					ll_row_top.removeView(ll_row_cb);
					
				} else {
					
					holder.cb = (CheckBox) convertView
							.findViewById(R.id.cb_completed);
//					holder.cb.setTag(childPosition);
				}

				holder.title = (TextView) convertView.findViewById(R.id.tv_task);
				holder.list = (TextView) convertView.findViewById(R.id.tv_list);
				holder.context = (TextView) convertView
						.findViewById(R.id.tv_row_context);
				holder.position = (TextView) convertView
						.findViewById(R.id.tv_row_pos);
				// holder.project = (TextView)
				// convertView.findViewById(R.id.tv_row_prj);
				holder.tags = (TextView) convertView.findViewById(R.id.tv_row_tag);
				holder.flag = (TextView) convertView.findViewById(R.id.tv_row_flag);

				convertView.setTag(holder);

			} else {
				
				holder = (ViewHolder) convertView.getTag();

//				if (taskStatus != C.TASK.CANCELLED)
//					holder.cb.setTag(childPosition);
			}
			
			fillData(holder, groupPosition, childPosition);

			return convertView;
		}
		
		private void fillData(final ViewHolder holder, final int groupPosition, final int childPosition) {
			
			// Priority
			String prior = (String) children.get(groupPosition).get(childPosition)
					.get("item_prior");
			if (prior.equals("无")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.none_prior));
				
			} else if (prior.equals("高")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.high_prior));
				
			} else if (prior.equals("中")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.medium_prior));
				
			} else if (prior.equals("低")) {
				
				holder.prior.setBackgroundColor(mRsrc.getColor(R.color.low_prior));
			}

			if (taskStatus != C.TASK.CANCELLED) {
				
				if (taskStatus == C.TASK.COMPLETED) {	// completed task
					
					holder.flag.setVisibility(View.VISIBLE);
					holder.cb.setChecked(true);
				}
				
				holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
					
					@Override
					public void onCheckedChanged(CompoundButton buttonView,
							boolean isChecked) {
						
						Log.e(TAG, "checkbox " + childPosition + " checked!");
						
						Calendar cld = Calendar.getInstance();
						
						HashMap<String, Object> hm = children.get(groupPosition).get(childPosition);
						long rowId = (Long) hm.get("item_id");
						TaskItem ti = mGa.getDbta().getTaskItem(rowId);
						
						String rmd = (String) hm.get("item_remind");		Log.e(TAG, "String rmd: " + rmd);
						if (rmd.length() > 0) {		// there is a remind
							
							mRemind = Calendar.getInstance();		// only when remind is set, $mRemind is not null
							
							try {
								Date date = mSdf.parse(rmd);
								mRemind.setTime(date);
								
							} catch (ParseException e) {
								
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							
							if (mRemind!=null && mRemind.after(cld)) {
								
								// remove or re-add this remind
								Intent i = new Intent(ViewTaskAct.this, DWTService.class);
								bindService(i, MyListAdapter.this, BIND_AUTO_CREATE);
							}
							
						}
						
						if (isChecked) {		// task is completed
							
							mChecked = true;
							holder.flag.setVisibility(View.VISIBLE);

							ti.setCompletedStatus(C.TASK.COMPLETED);
							mGa.getDbta().updateTask(rowId, ti);
							
							SharedPreferences prefs = getSharedPreferences(GTDApp.strList, GTDApp.MODE);
							Editor editor = prefs.edit();
							
							if (mListIndex != -1) {		// in some list
								
    							// update the counter
    							int count = (Integer) mGa.lists.get(mListIndex).get("item_count");
    							mGa.lists.get(mListIndex).put("item_count", count-1);
    							
    							editor.putInt("List_count["+mListIndex+"]", count-1);
    							
							} else {
								
								String list = ti.getListName();
								int index = TaskUtil.getListIndex(mGa.mList, list);
								
								int count = (Integer) mGa.lists.get(index).get("item_count");
    							mGa.lists.get(index).put("item_count", count-1);
    							
    							editor.putInt("List_count["+index+"]", count-1);
							}
							
							editor.commit();
							
						} else {		// move completed task into uncompleted
							
    						mChecked = false;
							holder.flag.setVisibility(View.INVISIBLE);

							ti.setCompletedStatus(C.TASK.UNCOMPLETED);
							mGa.getDbta().updateTask(rowId, ti);
							
							SharedPreferences prefs = getSharedPreferences(GTDApp.strList, GTDApp.MODE);
							Editor editor = prefs.edit();
							
							if (mListIndex != -1) {
								
								// update the counter
								int count = (Integer) mGa.lists.get(mListIndex).get("item_count");
								mGa.lists.get(mListIndex).put("item_count", count+1);
								
								
								editor.putInt("List_count["+mListIndex+"]", count+1);
								
							} else {
								
								// get original list index
								String list = ti.getListName();
								int index = TaskUtil.getListIndex(mGa.mList, list);
								
								Log.e(TAG, "original list and its index are: " + list + " " + index);
								
								int count = (Integer) mGa.lists.get(index).get("item_count");
								mGa.lists.get(index).put("item_count", count+1);
								
								
								editor.putInt("List_count["+index+"]", count+1);
							}
							
							editor.commit();
						}
						
						// unbind service
						if (mBound) {
							
							unbindService(MyListAdapter.this);
						}
						
					}		// end OnCheckedChanged
					
				});
				
			}

			holder.title.setText((String) children.get(groupPosition)
					.get(childPosition).get("item_name"));
			
			holder.list.setText("+"
					+ (String) children.get(groupPosition).get(childPosition).get("item_list"));

			String ctt = (String) children.get(groupPosition).get(childPosition)
					.get("item_context");
			if (ctt.equals(mGa.getContexts().get(0))) { // no context
				
				holder.context.setText("");
				
			} else {
				
				holder.context.setText("@" + ctt);
			}

			String pos = (String) children.get(groupPosition).get(childPosition).get("item_pos");
			if (pos.equals(mGa.getPositions().get(0).getPlace())) {
				
				holder.position.setText("");
				
			} else {
				
				holder.position.setText("&" + pos);
			}

			/*
			 * String prj = (String)
			 * children.get(groupPosition).get(childPosition).get("item_project");
			 * if (prj.equals(mGa.getProjects().get(0))) holder.project.setText("");
			 * else holder.project.setText("#"+prj);
			 */

			holder.tags.setText((String) children.get(groupPosition)
					.get(childPosition).get("item_tags"));
		}
		
		@Override
		public View newGroupView(boolean isExpanded, ViewGroup parent) {
			
			// TODO Auto-generated method stub
//			return super.newGroupView(isExpanded, parent);
			
			if (getSortIndex() > 0) {
				
				return 	mInflater.inflate(R.layout.group, parent, false);
				
			} else {
				
				return mInflater.inflate(R.layout.empty, parent, false);
			}
			
		}
		
		@Override
		public View getGroupView(int groupPosition, boolean isExpanded,
				View convertView, ViewGroup parent) {
			
			// TODO Auto-generated method stub
//			return super.getGroupView(groupPosition, isExpanded, convertView, parent);
			
			View v;
			v = newGroupView(isExpanded, parent);

			bindGroupView(v, groups.get(groupPosition), mGroupFrom, mGroupTo);
			
			return v;
		}
		
		private void bindGroupView(View view, Map<String, Object> data,
				String[] from, int[] to) {
			
			int len = to.length;

			for (int i = 0; i < len; i++) {
				
				TextView v = (TextView) view.findViewById(to[i]);
				if (v != null) {
					
					v.setText((String) data.get(from[i]));
				}
				
			}
			
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			
			Log.e(TAG, "bind successfully!");
			
			MyBinder binder = (MyBinder) service;
	        mService = binder.getService();
	        mBound = true;
	        
	        Log.e(TAG, "now will remove alarm of task: " + posInTable);
	        
	        {
	        	Date remind = mRemind.getTime();
	            Log.e(TAG, "remind: " + mSdf.format(remind));
	            Log.e(TAG, "current: " + mSdf.format(new Date()));
	        }
	        
	        if (mChecked) {
	        	
	            if (mRemind!=null && mRemind.after((Calendar.getInstance()))) {
	            	
	            	mService.removeSingleAlarm(posInTable);
	            }
	            
	        } else {		// unchecked, become uncompleted task
	        	
	        	if (mRemind!=null && mRemind.after(Calendar.getInstance())) {
	        		
	        		ArrayList<Long> id = new ArrayList<Long>();
	        		ArrayList<Calendar> rmd = new ArrayList<Calendar>();
	        		
	        		id.add(posInTable);
	        		rmd.add(mRemind);
	        		
	        		mService.setTaskID(id);
					mService.setRemindTime(rmd);
					mService.setAlarm();
	        	}
	        	
	        }
	        
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
			mService = null;
			mBound = false;
		}
		
	}		// end class MyListAdapter
	
	
	public static final int EDIT_TASK = Menu.FIRST;
	public static final int MOVE_TASK = Menu.FIRST+1;
	public static final int REMOVE_TASK = Menu.FIRST+2;
	private static final String TAG = "ViewTaskAct";
	
	private ArrayList<HashMap<String, Object>> groups = new ArrayList<HashMap<String, Object>>();
	private ArrayList<ArrayList<HashMap<String, Object>>> children =
			new ArrayList<ArrayList<HashMap<String, Object>>>();
	private MyListAdapter mAdapter;
	
	private ExpandableListView task_view;
	private long posInTable;
	private int mListIndex;
	private HashMap<String, Object> hmSelected;
	private GTDApp mGa;
	private int taskStatus;
	private ImageButton mReturn;
	private ImageButton btn_new;
	private int sortIndex;		// current sort type
	private EditText mQuickAdd;
	
	private final String[] mGroupFrom = new String[] { "group_name" };
	private final int[] mGroupTo = new int[] { R.id.tv_group };
	private final String[] fromCols = new String[] {
			"item_name",
			"item_context",
			"item_pos",
			"item_tags"};
	private final int[] toLayouts = new int[] {
			R.id.tv_task,
			R.id.tv_row_context,
			R.id.tv_row_pos,
			R.id.tv_row_tag};
	
	private Resources mRsrc;
	
	private Calendar calCur;
	private Calendar mRemind;
	private Calendar mSelectDay;
	
	private SimpleDateFormat mSdfDate = new SimpleDateFormat("yyyy-MM-dd");
	private SimpleDateFormat mSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	
	
	public int getSortIndex() {
		return sortIndex;
	}
	
	public ExpandableListView getListView() {
		return task_view;
	}
	
	public int getListIndex() {
		return mListIndex;
	}
	
	public int getTaskStatus() {
		return taskStatus;
	}
	
	/* (non-Javadoc)
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		
		Log.i(TAG, "onCreate Method is called!");
		
		
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.task_view);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.tb_cmn);
		
		mReturn = (ImageButton) findViewById(R.id.btn_return);
		btn_new = (ImageButton) findViewById(R.id.btn_new);
		task_view = (ExpandableListView) findViewById(R.id.elv_tasks);
		
		mGa = (GTDApp) getApplication();
		calCur = Calendar.getInstance();
		mSelectDay = Calendar.getInstance();
//		sortIndex = new ArrayList<Integer>();
		
		mRsrc = getResources();
		
		taskStatus = getIntent().getIntExtra("task_status", C.TASK.UNCOMPLETED);
		if (taskStatus == C.TASK.UNCOMPLETED) {
			
			mListIndex = getIntent().getIntExtra("list_index", -1);
			
		} else {		// completed or calcelled task
			
			mListIndex = -1;
		}
		
		
		restoreSortType(taskStatus, mListIndex);
		
		String title;
		if (taskStatus == C.TASK.UNCOMPLETED) {
			
			title = (String) mGa.lists.get(mListIndex).get("item_name");
			
		} else if (taskStatus == C.TASK.CANCELLED) {
			
			title = "垃圾箱";
			
//			mReturn.setVisibility(View.INVISIBLE);
			btn_new.setBackgroundResource(R.drawable.empty_enalbled);
			
		} else {			// completed task
			
			title = "已完成";
			
//			mReturn.setVisibility(View.INVISIBLE);
			btn_new.setVisibility(View.INVISIBLE);
		}
		((TextView) findViewById(R.id.tv_title)).setText(title);

		mAdapter = new MyListAdapter(
				this,
				groups,
				R.layout.group,
				mGroupFrom,
				mGroupTo,
				children,
				R.layout.row_task,
				fromCols,
				toLayouts);
		task_view.setAdapter(mAdapter);
		updateAdapterData();
		
		processTaskView();
		
		registerForContextMenu(task_view);
	}
	
	private void restoreSortType(int _taskStatus, int _listIndex) {
		
		Log.e(TAG, "_listIndex: " + _listIndex);
		
		if (_taskStatus == C.TASK.COMPLETED) {	// completed
			
			sortIndex = mGa.sortType.get("completed");
			
		} else if (_taskStatus == C.TASK.CANCELLED) {  // trash
			
			sortIndex = mGa.sortType.get("trash");
			
		} else {		// uncompleted
			
			switch (_listIndex) {
			
				case 0: // inbox
					sortIndex = mGa.sortType.get("inbox");
					break;
					
				case 1: // next
					sortIndex = mGa.sortType.get("next");
					break;
					
				case 2:		// agenda
					sortIndex = mGa.sortType.get("agenda");
					break;
					
				case 3:		// waiting
					sortIndex = mGa.sortType.get("waiting");
					break;
					
				case 4:		// memo
					sortIndex = mGa.sortType.get("memo");
					break;
					
				default:
					break;
			}
			
		}
		
	}
	
	@Override
	protected void onRestart() {
		// TODO Auto-generated method stub
		super.onRestart();
		
		Log.e(TAG, "onRestart is called");
		
	}
	
	public void updateAdapterData() {
		
		ArrayList<HashMap<String,Object>> items = null;
		HashMap<String, Object> hm;
		Cursor taskCursor = null;
		String sql = null;
		ArrayList<String> al = null;
		String list = "", where = "";
		int size;
		int[] index;
		String sortName = "";
		
		groups.clear();
		for (int i=0; i<children.size(); i++)
			children.get(i).clear();
		children.clear();
		
		if (mListIndex != -1) {
			
			list = (String) mGa.lists.get(mListIndex).get("item_name");
		}
		
		switch (sortIndex) {
		
			case 0:		// time(default)
				
				hm = new HashMap<String, Object>();
				hm.put("group_name", "按时间降序");
				groups.add(hm);
				
				if (taskStatus == C.TASK.COMPLETED) {		// completed task list
					sql = "select * from " + mGa.getDbta().getTableName()
						+ " where " + DBTaskAdapter.KEY_COMPLETED + "=" + C.TASK.COMPLETED
						+ " order by task_created desc";
				}
				else if (taskStatus == C.TASK.CANCELLED) {		// trash task list
					sql = "select * from " + mGa.getDbta().getTableName()
						+ " where " + DBTaskAdapter.KEY_COMPLETED + "=" + C.TASK.CANCELLED
						+ " order by task_created desc";
				}
				else {		// uncompleted
					sql = "select * from " + mGa.getDbta().getTableName()
						+ " where " + DBTaskAdapter.KEY_LIST + "=\"" + list
						+"\" AND "+DBTaskAdapter.KEY_COMPLETED + "=" + C.TASK.UNCOMPLETED
						+ " order by task_created desc";
				}
				taskCursor = mGa.getDbta().excuteSQL(sql);
				
				items = new ArrayList<HashMap<String,Object>>();
				fillArray(taskCursor, items);
				children.add(items);
				
				task_view.expandGroup(0);		// fix bug(empty layout)
				
				break;
				
			case 1:		// context
				
				al = mGa.getContexts();
				sortName = DBTaskAdapter.KEY_CONTEXT;
				
				break;
				
			case 2:		// location
				
//				al = mGa.getPositions();
				al = new ArrayList<String>();
				for (int i=0; i<mGa.getPositions().size(); i++) {
					
    				al.add(mGa.getPositions().get(i).getPlace());
    			}
				sortName = DBTaskAdapter.KEY_POS;
				
				break;
				
			case 3:		// project
				
				al = mGa.getProjects();
				sortName = DBTaskAdapter.KEY_PROJECT;
				
				break;
				
			case 4:		// priority
				
				al = mGa.prior;
				sortName = DBTaskAdapter.KEY_PRIOR;
				
				break;
				
			default:
				break;
		}
		
		if (sortIndex > 0) {
			
			size = al.size();
			index = new int[size];
			for (int i=0; i<size-1; i++)
				index[i] = i+1;
			index[size-1] = 0;
			
			for (int i : index) {
				
				if (taskStatus == C.TASK.UNCOMPLETED) {		// uncompleted task
					
					sql = "select * from " + mGa.getDbta().getTableName()
							+ " where " + sortName + "=\"" + al.get(i)
							+ "\" AND " + DBTaskAdapter.KEY_COMPLETED + "=" + C.TASK.UNCOMPLETED
							+ " AND " + DBTaskAdapter.KEY_LIST + "=\"" + list + "\""
							+ " order by task_created desc";
					
					/*where = sortName +"=\"" + al.get(i)
							+ "\" AND "+DBTaskAdapter.KEY_COMPLETED+"="+C.TASK.UNCOMPLETED
							+ " AND "+DBTaskAdapter.KEY_LIST+"=\""+list+"\"";*/
					
				} else if (taskStatus == C.TASK.COMPLETED) {		// completed task
					
					sql = "select * from " + mGa.getDbta().getTableName()
							+ " where " + sortName + "=\"" + al.get(i)
							+ "\" AND " + DBTaskAdapter.KEY_COMPLETED + "=" + C.TASK.COMPLETED
							+ " order by task_created desc";
					
					/*where = sortName +"=\"" + al.get(i)
							+ "\" AND "+DBTaskAdapter.KEY_COMPLETED+"="+C.TASK.COMPLETED;*/
					
				} else {		// trash
					
					sql = "select * from " + mGa.getDbta().getTableName()
							+ " where " + sortName + "=\"" + al.get(i)
							+ "\" AND " + DBTaskAdapter.KEY_COMPLETED + "=" + C.TASK.CANCELLED
							+ " order by task_created desc";
					
					/*where = sortName +"=\"" + al.get(i)
							+ "\" AND "+DBTaskAdapter.KEY_COMPLETED+"="+C.TASK.CANCELLED;*/
					
				}
				
				taskCursor = mGa.getDbta().excuteSQL(sql);
				if (taskCursor.getCount() == 0)
					continue;
				
				hm = new HashMap<String, Object>();
				hm.put("group_name", al.get(i));
				groups.add(hm);
				
				Log.e(TAG, "number of group " + al.get(i) + ": " + taskCursor.getCount());
				
				items = new ArrayList<HashMap<String, Object>>();
				fillArray(taskCursor, items);
				children.add(items);
			}
			
			for (int i=0; i<groups.size(); i++)
				task_view.expandGroup(i);
		}
		
		taskCursor.close();
		
		mAdapter.notifyDataSetChanged();
	}
	
	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
		
		Log.e(TAG, "onStart is called");
		
//		updateAdapterData();
	}
	
	/**
	 * fill array $item with the specific condition
	 * @param taskCursor
	 */
	private void fillArray(Cursor taskCursor, ArrayList<HashMap<String, Object>> items) {
		HashMap<String, Object> hm;
		
		if (taskCursor.moveToFirst()) {
			do {
				long rowId = taskCursor.getLong(DBTaskAdapter.COL_ID);
				String task = taskCursor.getString(DBTaskAdapter.COL_TASK_NAME);
				String note = taskCursor.getString(DBTaskAdapter.COL_TASK_NOTE);
				String list = taskCursor.getString(DBTaskAdapter.COL_TASK_LIST);
				
				String ctt = taskCursor.getString(DBTaskAdapter.COL_TASK_CONTEXT);
				String prj = taskCursor.getString(DBTaskAdapter.COL_TASK_PROJECT);
				String pos = taskCursor.getString(DBTaskAdapter.COL_TASK_POS);
				
				int status = taskCursor.getInt(DBTaskAdapter.COL_TASK_STATUS);
				String st = taskCursor.getString(DBTaskAdapter.COL_TASK_ST);
				String et = taskCursor.getString(DBTaskAdapter.COL_TASK_ET);
				String repeat = taskCursor.getString(DBTaskAdapter.COL_TASK_REPEAT);
				String remind = taskCursor.getString(DBTaskAdapter.COL_TASK_REMIND);
				
				String prior = taskCursor.getString(DBTaskAdapter.COL_TASK_PRIOR);
				String tags = taskCursor.getString(DBTaskAdapter.COL_TASK_TAG);
				String created = taskCursor.getString(DBTaskAdapter.COL_TASK_CREATED);
				int completed = taskCursor.getInt(DBTaskAdapter.COL_TASK_COMPLETED);
				
				
				hm = new HashMap<String, Object>();
				hm.put("item_id", rowId);
				hm.put("item_name", task);
				hm.put("item_note", note);
				hm.put("item_list", list);
				
				hm.put("item_context", ctt);
				hm.put("item_project", prj);
				hm.put("item_pos", pos);
				
				hm.put("item_status", status);
				hm.put("item_st", st);
				hm.put("item_et", et);
				hm.put("item_repeat", repeat);
				hm.put("item_remind", remind);
				
				hm.put("item_prior", prior);
				hm.put("item_tags", tags);
				hm.put("item_created", created);
				hm.put("item_completed", completed);
				
				items.add(hm);
			} while (taskCursor.moveToNext());
		}
	}
	
	/*public void updateAdapterData() {
		Cursor taskCursor;
		
		items.clear();
		
		if (taskStatus == C.TASK.COMPLETED) {		// completed task list
			taskCursor = mGa.getDbta().fetchTasks(DBTaskAdapter.KEY_COMPLETED+"="+C.TASK.COMPLETED);
		} else if (taskStatus == C.TASK.CANCELLED) {		// trash task list
			taskCursor = mGa.getDbta().fetchTasks(DBTaskAdapter.KEY_COMPLETED+"="+C.TASK.CANCELLED);
		} else {
			String list = mGa.lists.get(mListIndex);
			String where = DBTaskAdapter.KEY_LIST+"=\""+list
					+"\" AND "+DBTaskAdapter.KEY_COMPLETED+"="+C.TASK.UNCOMPLETED;
			taskCursor = mGa.getDbta().fetchTasks(where);
		}
		fillArray(taskCursor, items);
		
		mAdapter.notifyDataSetChanged();
	}*/
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenu.ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		
		ExpandableListView.ExpandableListContextMenuInfo info =
				(ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
		int type = ExpandableListView.getPackedPositionType(info.packedPosition);
//		int group = ExpandableListView.getPackedPositionGroup(info.packedPosition);
//		int child = ExpandableListView.getPackedPositionChild(info.packedPosition);
		
		//Only create a context menu for child items
		if (type == 1) {
			menu.setHeaderTitle("编辑任务");
			
			if (taskStatus != C.TASK.CANCELLED) {
				menu.add(0, EDIT_TASK, 1, "编辑");
				menu.add(0, REMOVE_TASK, 2, "删除");
			}
			menu.add(0, MOVE_TASK, 0, "移动到");
		}
		
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		
		Log.e(TAG, "onDestroy is called");
		
//		if (mBound)
//			unbindService(this);
	}
	
	/* (non-Javadoc)
	 * @see android.app.Activity#onContextItemSelected(android.view.MenuItem)
	 */
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		
		// TODO Auto-generated method stub
		super.onContextItemSelected(item);
		
		int type, groupPos = 0, childPos = 0;
		
		ExpandableListContextMenuInfo info =
				(ExpandableListContextMenuInfo) item.getMenuInfo();
		type = ExpandableListView.getPackedPositionType(info.packedPosition);
		if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
			
			groupPos = ExpandableListView.getPackedPositionGroup(info.packedPosition);
			childPos = ExpandableListView.getPackedPositionChild(info.packedPosition);
		}
		
//		Toast.makeText(ViewTaskAct.this, "group: "+groupPos+" child: "+childPos, Toast.LENGTH_LONG);
		Log.e(TAG, "group: "+groupPos+" child: "+childPos+" clicked!");
		
		hmSelected = (HashMap<String, Object>) children.get(groupPos).get(childPos);
		posInTable = (Long) hmSelected.get("item_id");
		
		String rmd = (String) hmSelected.get("item_remind");
		if (rmd.length() > 0) {
			
			mRemind = Calendar.getInstance();		// only when remind is set, $mRemind is not null
			
			try {
				Date date = mSdf.parse(rmd);
				mRemind.setTime(date);
				
			} catch (ParseException e) {
				
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
		/*if (taskStatus != C.TASK.UNCOMPLETED) {
			String list = (String) hmSelected.get("item_list");
			mListIndex = mGa.lists.indexOf(list);
		}*/

		
		switch (item.getItemId()) {
		
			case EDIT_TASK:
				
				/*Intent itt = new Intent(ViewTaskAct.this, NewTaskAct.class);
				
				itt.putExtra("row_id", posInTable);
				itt.putExtra("task_data", hashMap2Task(hmSelected));
				itt.putExtra("list_index", mListIndex);
				
				startActivityForResult(itt, 0);*/
				
				TaskUtil.editTask(ViewTaskAct.this, mListIndex, posInTable);
				
				return true;
				
			case MOVE_TASK:
				
//				moveTask();
				
				mGa.mRefresh = true;
				TaskUtil.moveTask(ViewTaskAct.this, mListIndex, posInTable);
				
				return true;
			
			case REMOVE_TASK: // remove a task
				
//				removeTask();
				
				mGa.mRefresh = true;
				TaskUtil.removeTask(ViewTaskAct.this, mListIndex, posInTable);
				
				return true;
				
			default:
				break;
		}
		
		return false;
	}
	
	private void processTaskView() {
		
		mQuickAdd = (EditText) findViewById(R.id.et_quick_add);
		mQuickAdd.setOnEditorActionListener(this);
		if (taskStatus != C.TASK.UNCOMPLETED) {
			
			mQuickAdd.setVisibility(View.GONE);
		}
		
		task_view.setGroupIndicator(null);
		for (int i=0; i<groups.size(); i++)
			task_view.expandGroup(i);
		
		if (taskStatus == C.TASK.COMPLETED) {		// completed
			
			btn_new.setVisibility(View.INVISIBLE);
			
		} else if (taskStatus == C.TASK.CANCELLED) {		// trash
			
//			btn_new.setText("清空");
			
			boolean isEmpty = true;
			for (int i=0; i<groups.size(); i++) {
				
				if (children.get(i).size() > 0) {
					
					isEmpty = false;
					break;
				}
				
			}
			
			if (isEmpty)	{	// no trash
				
				btn_new.setEnabled(false);
				btn_new.setBackgroundResource(R.drawable.empty_disabled);
			}
			
			btn_new.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					AlertDialog.Builder builder = new AlertDialog.Builder(ViewTaskAct.this);
					builder.setTitle("是否要永久清空\"垃圾箱\"中的所有任务？");
					
					builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface dialog, int which) {
							
							for (int i=0; i<groups.size(); i++) {
								
								for (int j=0; j<children.get(i).size(); j++) {
									
									long rowId = (Long) children.get(i).get(j).get("item_id");
									mGa.getDbta().removeTask(rowId);
								}
								
							}
							
							updateAdapterData();
							
							btn_new.setEnabled(false);
							btn_new.setBackgroundResource(R.drawable.empty_disabled);
						}
					});
					builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
							dialog.dismiss();
						}
					});
					builder.show();
				}
			});
			
			btn_new.setOnTouchListener(new OnTouchListener() {
				
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					
					if (event.getAction() == MotionEvent.ACTION_DOWN) {
						
						v.setBackgroundResource(R.drawable.empty_pressed);
						
					} else if (event.getAction() == MotionEvent.ACTION_UP) {
						
						v.setBackgroundResource(R.drawable.empty_enalbled);
					}

					return false;
				}
				
			});
			
		} else {		// uncompleted task
			
			btn_new.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					
					// TODO Auto-generated method stub
					Intent itt = new Intent(ViewTaskAct.this, NewTaskAct.class);
					
					itt.putExtra("task_status", taskStatus);
					itt.putExtra("list_index", mListIndex);
					itt.putExtra("new_task", true);
					
					startActivityForResult(itt, 0);
				}
				
			});
			
			btn_new.setOnTouchListener(new OnTouchListener() {
				
				@Override
				public boolean onTouch(View v, MotionEvent event) {
					
					if (event.getAction() == MotionEvent.ACTION_DOWN) {
						
						v.setBackgroundResource(R.drawable.add_btn_pressed);
						
					} else if (event.getAction() == MotionEvent.ACTION_UP) {
						
						v.setBackgroundResource(R.drawable.add_task);
					}
					
					return false;
				}
			});
			
		}
		
		ImageButton btn_return = (ImageButton) findViewById(R.id.btn_return);
		btn_return.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				
				finish();
			}
			
		});
		
		btn_return.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					
					v.setBackgroundResource(R.drawable.back_pressed);
					
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					
					v.setBackgroundResource(R.drawable.back);
				}

				return false;
			}
			
		});
		
		/*OnItemLongClickListener oilsl = new OnItemLongClickListener() {
			@SuppressWarnings("unchecked")
			public boolean onItemLongClick(AdapterView<?> parent, View v,
					int pos, long id) {
				// TODO Auto-generated method stub
				hmSelected = (HashMap<String, Object>) task_view.get(groupPosition).get(childPosition);
				posInTable = (Long) hmSelected.get("item_id");
				
				if (taskStatus != C.TASK.UNCOMPLETED) {
					String list = (String) hmSelected.get("item_list");
					mListIndex = mGa.lists.indexOf(list);
				}
				
				Log.e(TAG, "mListIndex is: "+mListIndex);
				// setTitle("long click"+current_str);

				return false;
			}
		};*/
		
		OnChildClickListener ocl = new OnChildClickListener() {
			
			@Override
			public boolean onChildClick(ExpandableListView parent, View v,
					int groupPosition, int childPosition, long id) {
				
				// TODO Auto-generated method stub
				hmSelected = (HashMap<String, Object>) children.get(groupPosition).get(childPosition);
				TaskItem task = hashMap2Task(hmSelected);
				
				posInTable = (Long) hmSelected.get("item_id");
				
				if (taskStatus != C.TASK.UNCOMPLETED) {
					
					String list = (String) hmSelected.get("item_list");
					mListIndex = mGa.lists.indexOf(list);
				}
				Log.e(TAG, "mListIndex is: "+mListIndex);
				
				Intent itt = new Intent(ViewTaskAct.this, TaskDetailAct.class);
				
				itt.putExtra("row_id", posInTable);
				itt.putExtra("list_index", mListIndex);
				itt.putExtra("task", task);
				
				Log.e(TAG, "mListIndex passed into is: "+ mListIndex);
				
				/*itt.putExtra("list_index", mListIndex);
				itt.putExtra("task_status", taskStatus);*/
				
				startActivity(itt);
				
				return false;
			}
		};
		task_view.setOnChildClickListener(ocl);
	}
	
	private TaskItem hashMap2Task(HashMap<String, Object> hm) {
		
		TaskItem task;
		
		String name = (String) hm.get("item_name");
		String note = (String) hm.get("item_note");
		String list = (String) hm.get("item_list");
		task = new TaskItem(name, note, list);
		
		task.setContext((String) hm.get("item_context"));
		task.setProject((String) hm.get("item_project"));
		task.setPosition((String) hm.get("item_pos"));
		
		if (((Integer) hm.get("item_status")) == 1)
			task.setAllDay(true);
		else
			task.setAllDay(false);
		
		task.setStartTime((String) hm.get("item_st"));
		task.setEndTime((String) hm.get("item_et"));
		task.setRepeat((String) hm.get("item_repeat"));
		task.setRemind((String) hm.get("item_remind"));
		task.setPrior((String) hm.get("item_prior"));
		task.setTags((String) hm.get("item_tags"));
		task.setCreated((String) hm.get("item_created"));
		task.setCompletedStatus((Integer) hm.get("item_completed"));
		
		return task;
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		super.onCreateOptionsMenu(menu);
		
//		MenuItem itemSort = menu.add(0, C.MENU.SORT, 0, "排序");
//		MenuItem itemHome = menu.add(0, C.MENU.HOME, 1, "主页");
		
		menu.add(0, C.MENU.SORT, 0, "排序");
//		menu.add(0, C.MENU.HOME, 1, "主页");
		
//		itemSort.setIcon(R.drawable.add_new_item);
		
		return true;
	}
	
	private void saveSortType(int _taskStatus, int _listIndex, int _sortType) {
		
		Editor edit = mGa.getSpSortType().edit();
		
		if (_taskStatus == C.TASK.COMPLETED) {	// completed
			
			mGa.sortType.put("completed", _sortType);
			edit.putInt("completed", _sortType);
			
		} else if (_taskStatus == C.TASK.CANCELLED) {  // trash
			
			mGa.sortType.put("trash", _sortType);
			edit.putInt("trash", _sortType);
			
		} else {		// uncompleted
			
			switch (_listIndex) {
			
				case 0: 	// inbox
					mGa.sortType.put("inbox", _sortType);
					edit.putInt("inbox", _sortType);
					break;
					
				case 1: 	// next
					mGa.sortType.put("next", _sortType);
					edit.putInt("next", _sortType);
					break;
					
				case 2:		// agenda
					mGa.sortType.put("agenda", _sortType);
					edit.putInt("agenda", _sortType);
					break;
					
				case 3:		// waiting
					mGa.sortType.put("waiting", _sortType);
					edit.putInt("waiting", _sortType);
					break;
					
				case 4:		// memo
					mGa.sortType.put("memo", _sortType);
					edit.putInt("memo", _sortType);
					break;
					
				default:
					break;
			}
			
		}

		edit.commit();
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		// TODO Auto-generated method stub
		super.onOptionsItemSelected(item);
		
		switch (item.getItemId()) {
		
			case C.MENU.SORT:
				
				AlertDialog.Builder builder = new AlertDialog.Builder(ViewTaskAct.this);
				builder.setTitle("排序");
				
				final String[] sortItems = (String[]) mGa.getSort().toArray(new String[mGa.getSort().size()]);
				builder.setSingleChoiceItems(sortItems, sortIndex, new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						if (which != sortIndex) {
							sortIndex = which;
							
							updateAdapterData();
							saveSortType(taskStatus, mListIndex, sortIndex);
						}
						
						dialog.dismiss();
					}
				});
				
				builder.show();
				
				break;
				
			case C.MENU.HOME:
				break;
				
			default:
				break;
		}
		
		return true;
	}

	/*@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
		// TODO Auto-generated method stub
		Log.e(TAG, "bind successfully!");
		
		MyBinder binder = (MyBinder) service;
        mService = binder.getService();
        mBound = true;
        
        Log.e(TAG, "now will remove alarm of task: "+posInTable);
        
        if (mRemind!=null && mRemind.after((Calendar.getInstance())))
        	mService.removeSingleAlarm(posInTable);
	}

	@Override
	public void onServiceDisconnected(ComponentName name) {
		// TODO Auto-generated method stub
		mService = null;
		mBound = false;
	}*/

	@Override
	public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
		// TODO Auto-generated method stub
		
		if (actionId == EditorInfo.IME_ACTION_DONE) {
			
			String str = mQuickAdd.getText().toString();
			
			if (str.length() == 0) {
				
				Toast.makeText(this, "任务不能为空", Toast.LENGTH_LONG).show();
				
				return true;
			}
			
			// create a new task
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			TaskItem newTask = new TaskItem(
					str,
					"",
					(String) mGa.lists.get(mListIndex).get("item_name"));
			
			newTask.setContext(mGa.getContexts().get(0));
			newTask.setProject(mGa.getProjects().get(0));
			newTask.setPosition(mGa.getPositions().get(0).getPlace());
			
			if (mListIndex == GTDApp.AGENDA) {
				
				Calendar cld = Calendar.getInstance();
				
				newTask.setAllDay(true);
				newTask.setStartTime(mSdf.format(cld.getTime()));
				newTask.setEndTime(mSdf.format(cld.getTime()));
				newTask.setRepeat("");
			} 
			
			newTask.setRemind("");
			newTask.setTags("");
			
			newTask.setCreated(sdf.format(Calendar.getInstance().getTime()));
			
			mGa.getDbta().insertTask(newTask);
			updateAdapterData();

			
			// update the counter
			int count = (Integer) mGa.lists.get(mListIndex).get("item_count");
			mGa.lists.get(mListIndex).put("item_count", ++count);
			
			SharedPreferences prefs = getSharedPreferences(GTDApp.strList, GTDApp.MODE);
			Editor editor = prefs.edit();
			
			editor.putInt("List_count[" + mListIndex + "]", count);
			editor.commit();
			
			mQuickAdd.setText("");
			
			Toast.makeText(this, getString(R.string.msg_add_task), Toast.LENGTH_LONG).show();
		}

		return false;
	}
	
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		
		Log.e(TAG, "onResume is called!");
		
		updateAdapterData();
	}
	
	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		
		Log.e(TAG, "onStop is called!");
	}
	
}
